iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 28
0

lift-json

這裡介紹使用 lift-json 的套件(lift-json_2.12-3.1.1.jar),來對 json 格式資料做處理.需先將 jar 檔放到執行 scala 的目錄底下(/Volumes/Transcend/scala-test/),再使用:require 指令把 jar 檔 add 到 classpath :

scala> :require lift-json_2.12-3.1.1.jar
Added '/Volumes/Transcend/scala-test/lift-json_2.12-3.1.1.jar' to classpath.

scala> :require paranamer-2.8.jar
Added '/Volumes/Transcend/scala-test/paranamer-2.8.jar' to classpath.

需 import 下列兩個套件 :

scala> import net.liftweb.json._
import net.liftweb.json._

scala> import net.liftweb.json.Serialization.write
import net.liftweb.json.Serialization.write

需加上 implicit val formats = DefaultFormats

scala> case class Address(city: String, state: String)
defined class Address

scala> case class Person(name: String, address: Address)
defined class Person

scala> implicit val formats = DefaultFormats
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@ac417a2

將物件轉成 json 格式 :

scala> val p = Person("Daniel", Address("Daniel", "Taipei"))
p: Person = Person(Daniel,Address(Daniel,Taipei))

scala> val jsonString = write(p)
jsonString: String = {"name":"Daniel","address":{"city":"Daniel","state":"Taipei"}}

將 json string 轉成 object :

scala> parse(""" { "numbers" : [1, 2, 3, 4] } """)
res0: net.liftweb.json.JValue = JObject(List(JField(numbers,JArray(List(JInt(1), JInt(2), JInt(3), JInt(4))))))

轉成自訂義的物件(MyNumbers) :

scala> case class MyNumbers(numbers: Array[Int])
defined class MyNumbers

scala> val jvalue = parse(""" { "numbers" : [1, 2, 3, 4] } """)
jvalue: net.liftweb.json.JValue = JObject(List(JField(numbers,JArray(List(JInt(1), JInt(2), JInt(3), JInt(4))))))

scala> val myNum = jvalue.extract[MyNumbers]
myNum: MyNumbers = MyNumbers([I@539fe2b8)

scala> for(num <- myNum.numbers) println(num)
1
2
3
4

使用 DSL 做轉換 :

scala> import net.liftweb.json.JsonDSL._
import net.liftweb.json.JsonDSL._

scala> val json = List(1, 2, 3)
json: List[Int] = List(1, 2, 3)

scala> compact(render(json))
<console>:21: warning: method compact in package json is deprecated (since 3.0): Please switch to using compactRender instead.
       compact(render(json))
       ^
<console>:21: warning: method render in package json is deprecated (since 3.0): Please switch to using prettyRender or compactRender instead.
       compact(render(json))
               ^
res1: String = [1,2,3]

compact(render(json)) 的方式已經被 deprecated,所以改用 compactRender.
Tuple2 轉 json :

scala> val json = ("name" -> "joe")
json: (String, String) = (name,joe)

scala> compactRender(json)
res3: String = {"name":"joe"}

使用 ~ 符號 :

scala> val json = ("name" -> "joe") ~ ("age" -> 35) ~ ("tel" -> "12345")
json: net.liftweb.json.JsonAST.JObject = JObject(List(JField(name,JString(joe)), JField(age,JInt(35)), JField(tel,JString(12345))))

scala> compactRender(json)
res4: String = {"name":"joe","age":35,"tel":"12345"}

型態如果是 Option ,None 物件就不會轉了 :

scala> val json = ("name" -> "joe") ~ ("age" -> Some(35))
json: net.liftweb.json.JsonAST.JObject = JObject(List(JField(name,JString(joe)), JField(age,JInt(35))))

scala> compactRender(json)
res5: String = {"name":"joe","age":35}

scala> val json = ("name" -> "joe") ~ ("age" -> (None:Option[Int]))
json: net.liftweb.json.JsonAST.JObject = JObject(List(JField(name,JString(joe)), JField(age,JNothing)))

scala> compactRender(json)
res7: String = {"name":"joe"}

總結


  • scala 處理 json 時還有其他選項,例如 json4s-jackson 或 json4s-native,json4s-jackson 與 json4s-native 的差異是 jackson 包含了大部分 jackson-module-scala 的功能,也可以使用 lift-json 下的所有功能。

參考資料


lift-json : https://github.com/lift/lift/tree/master/framework/lift-base/lift-json


上一篇
Scala day 27 (Write Files)
下一篇
Scala day 29 (some collection method)
系列文
認識scala30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言